package com.seean.spark.utils

import java.text.SimpleDateFormat
import java.util.Properties
import java.util.regex.Pattern

import com.seean.spark.model.base.BaseModel
import org.apache.spark.sql.{DataFrame, Row, SaveMode}

/**
  * 工具类
  *
  * @authur wsx
  * @date 2020/6/24 15:26
  */
object Utils extends Serializable {

  /**
    * listToRDD
    * @param pars
    * @tparam T
    * @return
    */
  def listToRDD[T<:BaseModel](pars:List[T])= pars.map(item=>Row(item.toList():_*))

  val properties=PropertiesUtil.loadProperties()
  val connection = properties.getProperty("db.connection")
  val dbName = properties.getProperty("db.name")
  val dbPwd = properties.getProperty("db.pwd")

  /**
    * 数据库 批量插入
    * @param df
    * @param tableName
    */
  def dfBacthWrite(df:DataFrame,tableName:String): Unit ={
    val property = new Properties()
    property.put("user", dbName)
    property.put("password", dbPwd)
    df.write.mode(SaveMode.Append).jdbc(connection,tableName,property)
  }

  /**
    * 判断是否包含特殊字符
    * @param checkStr
    * @return
    */
  def checkSpecialCharactersExist(checkStr:String):Boolean={
   if(checkStr==null) return false
    val regEx = "[ _`~!@#$%^&*+=|{}':;'\\[\\].<>/?~！@#￥%……&*——+|{}【】‘；：”“’。？]|\n|\r|\t"; //去掉了中英文的  、，（）
    val p = Pattern.compile(regEx)
    p.matcher(checkStr).find()
  }

  /**
    * 身份证号规则验证
    * @param idcard
    * @return
    */
  def regexIdCard(idcard:String):Boolean={
    if(idcard==null) return false
    var cityCode = Map("11"->"", "12"->"", "13"->"", "14"->"", "15"->"", "21"->"", "22"->"",
      "23"->"", "31"->"", "32"->"", "33"->"", "34"->"", "35"->"", "36"->"",
      "37"->"", "41"->"", "42"->"", "43"->"", "44"->"", "45"->"", "46"->"", "50"->"",
      "51"->"", "52"->"", "53"->"", "54"->"", "61"->"", "62"->"", "63"->"", "64"->"",
      "65"->"", "71"->"", "81"->"", "82"->"", "91"->"")
    if (idcard.length  == 18) {
      // 获取前17位
      val idcard17 = idcard.substring(0, 17)
      // 前17位全部为数字
      if (!idcard17.matches("^[0-9]*$"))return false
      val provinceid = idcard.substring(0, 2)
      // 校验省份
      if (!cityCode.contains(provinceid)) return false
      // 校验出生日期
      val birthday = idcard.substring(6, 14)
      val sdf = new SimpleDateFormat("yyyyMMdd")
      try {
        val birthDate = sdf.parse(birthday)
        val tmpDate = sdf.format(birthDate)
        // 出生年月日不正确
        if (!(tmpDate == birthday)) return false
      } catch {
        case e: Exception => return false
      }
      // 获取第18位
      val idcard18Code = idcard.substring(17, 18)
      val PowerSum = idcard17.charAt(0).toString.toInt * 7 + idcard17.charAt(1).toString.toInt * 9 +
        idcard17.charAt(2).toString.toInt * 10 + idcard17.charAt(3).toString.toInt * 5 +
        idcard17.charAt(4).toString.toInt * 8 + idcard17.charAt(5).toString.toInt * 4 +
        idcard17.charAt(6).toString.toInt * 2 + idcard17.charAt(7).toString.toInt * 1 +
        idcard17.charAt(8).toString.toInt * 6 + idcard17.charAt(9).toString.toInt * 3 +
        idcard17.charAt(10).toString.toInt * 7 + idcard17.charAt(11).toString.toInt * 9 +
        idcard17.charAt(12).toString.toInt * 10 + idcard17.charAt(13).toString.toInt * 5 +
        idcard17.charAt(14).toString.toInt * 8 + idcard17.charAt(15).toString.toInt * 4 +
        idcard17.charAt(16).toString.toInt * 2
      var checkCode:String = null
      PowerSum % 11 match {
        case 10 => checkCode = "2"
        case 9 => checkCode = "3"
        case 8 => checkCode = "4"
        case 7 => checkCode = "5"
        case 6 => checkCode = "6"
        case 5 => checkCode = "7"
        case 4 => checkCode = "8"
        case 3 => checkCode = "9"
        case 2 => checkCode = "x"
        case 1 => checkCode = "0"
        case 0 => checkCode = "1"
        case _ => return false
      }
      if (null == checkCode) return false
      if (!idcard18Code.equalsIgnoreCase(checkCode)) return false
      return true
    }else if(idcard.length  == 15){
      // 15位全部为数字
      if (!idcard.matches("^[0-9]*$"))return false
      val provinceid = idcard.substring(0, 2)
      // 校验省份
      if (!cityCode.contains(provinceid)) return false
      // 校验出生日期
      val birthday = idcard.substring(6, 12)
      val sdf = new SimpleDateFormat("yyMMdd")
      try {
        val birthDate = sdf.parse(birthday)
        val tmpDate = sdf.format(birthDate)
        // 出生年月日不正确
        if (!(tmpDate == birthday)) return false
      } catch {
        case e: Exception => return false
      }
      return true
    }
    false
  }

  /**
    * 邮箱规则验证
    * @param checkStr
    * @return
    */
  def checkPostcode(checkStr:String):Boolean={
    if(checkStr==null) return false
    val regEx ="[1-9]\\d{5}"
    val p = Pattern.compile(regEx)
    p.matcher(checkStr).find()
  }

  /**
    *  手机号码规则验证
    * @param checkStr
    * @return
    */
  def checkMobile(checkStr:String):Boolean={
    if(checkStr==null) return false
    val regEx ="(\\+\\d+)?1[345789]\\d{9}$"
    val p = Pattern.compile(regEx)
    p.matcher(checkStr).find()
  }
  /**
    *  固定电话号码规则验证
    * @param checkStr
    * @return
    */
  def checkPhone(checkStr:String):Boolean={
    if(checkStr==null) return false
    val regEx ="(\\+\\d+)?(\\d{3,4}\\-?)?\\d{7,8}$"
    val p = Pattern.compile(regEx)
    p.matcher(checkStr).find()
  }



}
